/**
 * @author Jorge Mejuto Created on 11-mar-2005
 */
package net.eyra.utiles;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFDataFormat;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.Region;
import org.apache.poi.ss.usermodel.DataFormat;

public class XLSDao {

    public static final short ESTILO_ALINEADO_CENTRO = HSSFCellStyle.ALIGN_CENTER;
    public static final short ESTILO_ALINEADO_DERECHA = HSSFCellStyle.ALIGN_RIGHT;
    public static final short ESTILO_ALINEADO_IZQUIERDA = HSSFCellStyle.ALIGN_LEFT;
    public static final short ESTILO_ALINEADO_VERTICAL_CENTRADO = HSSFCellStyle.VERTICAL_CENTER;
    public static final short ESTILO_ALINEADO_VERTICAL_ARRIBA = HSSFCellStyle.VERTICAL_TOP;
    public static final short ESTILO_ALINEADO_VERTICAL_ABAJO = HSSFCellStyle.VERTICAL_BOTTOM;

    public static final short ESTILO_TEXTO_NEGRILLA = HSSFFont.BOLDWEIGHT_BOLD;
    public static final short ESTILO_TEXTO_NORMAL = HSSFFont.BOLDWEIGHT_NORMAL;
    public static final short ESTILO_TEXTO_COLOR_NORMAL = HSSFFont.COLOR_NORMAL;
    public static final short ESTILO_TEXTO_COLOR_ROJO = HSSFFont.COLOR_RED;

    public static final short COLOR_NEGRO = 8;
    public static final short COLOR_BLANCO = 9;
    public static final short COLOR_ROJO = 10;
    public static final short COLOR_VERDE = 17;
    public static final short COLOR_NAVY = 18;
    public static final short COLOR_AMARILLO = 13;
    public static final short COLOR_MORADO = 36;
    public static final short COLOR_AZUL = 12;
    public static final short COLOR_LILA = 20;
    public static final short COLOR_ORO = 51;
    public static final short COLOR_TEAL = 21;
    public static final short COLOR_ROSA = 14;
    public static final short COLOR_MARRON = 60;
    public static final short COLOR_NARANJA = 52;
    public static final short COLOR_GRIS = 23;

    public static final short TIPO_DATO_BLANCO = HSSFCell.CELL_TYPE_BLANK;
    public static final short TIPO_DATO_BOOLEANO = HSSFCell.CELL_TYPE_BOOLEAN;
    public static final short TIPO_DATO_NUMERICO = HSSFCell.CELL_TYPE_NUMERIC;
    public static final short TIPO_DATO_TEXTO = HSSFCell.CELL_TYPE_STRING;
    public static final short TIPO_DATO_FORMULA = HSSFCell.CELL_TYPE_FORMULA;

    public static final short BORDE_NORMAL = HSSFCellStyle.BORDER_MEDIUM;
    public static final short BORDE_DELGADO = HSSFCellStyle.BORDER_THIN;
    public static final short BORDE_GRUESO = HSSFCellStyle.BORDER_THICK;

    private HSSFWorkbook libro = null;
    private HSSFSheet hoja = null;
    private HSSFRow fila = null;
    private HSSFCell celda = null;

    // private HSSFCellStyle estilo = null;
    // private HSSFFont font = null;

    public void borrarFila(int numero_fila) {
        hoja.removeRow(hoja.getRow(numero_fila - 1));
    }

    public void borrarHoja(String nombre_hoja) {
        libro.removeSheetAt(getNumeroHoja(nombre_hoja));
    }

    /*
     * Metodos para el manejo de las celdas de las filas de una Hoja del Libro Excel.
     */
    public void crearCelda(int numero_columna) {
        celda = fila.createCell(numero_columna - 1);
        celda.setAsActiveCell();
    }

    /*
     * Metodos para el manejo de las filas de una Hoja del Libro Excel.
     */
    public void crearFila(int numero_fila) {
        fila = hoja.createRow(numero_fila - 1);
    }

    /*
     * Metodos para el manejo de Hojas del Libro Excel.
     */
    public int crearHoja(String nombre_hoja) {
        hoja = libro.createSheet(nombre_hoja);
        return getNumeroHoja(nombre_hoja);
    }

    public void crearRegion(int fila_inicial, int columna_inicial, int fila_final, int columna_final, double numero, HSSFCellStyle estilo) {
        Region region = new Region((short) (fila_inicial - 1), (short) (columna_inicial - 1), (short) (fila_final - 1), (short) (columna_final - 1));
        hoja.addMergedRegion(region);
        for (int x = fila_inicial; x < fila_final + 1; x++) {
            crearFila(x);
            for (int y = columna_inicial; y < columna_final + 1; y++) {
                crearCelda(y);
                celda.setCellStyle(estilo);
            }
        }
        escribirNumero(fila_inicial, columna_inicial, numero, estilo);
    }

    public void crearRegion(int fila_inicial, int columna_inicial, int fila_final, int columna_final, HSSFCellStyle estilo) {
        Region region = new Region((short) (fila_inicial - 1), (short) (columna_inicial - 1), (short) (fila_final - 1), (short) (columna_final - 1));
        hoja.addMergedRegion(region);
        for (int x = fila_inicial; x < fila_final + 1; x++) {
            crearFila(x);
            for (int y = columna_inicial; y < columna_final + 1; y++) {
                crearCelda(y);
                celda.setCellStyle(estilo);
            }
        }
    }

    public void crearRegion(int fila_inicial, int columna_inicial, int fila_final, int columna_final, String texto, HSSFCellStyle estilo) {
        Region region = new Region((short) (fila_inicial - 1), (short) (columna_inicial - 1), (short) (fila_final - 1), (short) (columna_final - 1));
        hoja.addMergedRegion(region);
        for (int x = fila_inicial; x < fila_final + 1; x++) {
            crearFila(x);
            for (int y = columna_inicial; y < columna_final + 1; y++) {
                crearCelda(y);
                celda.setCellStyle(estilo);
            }
        }
        escribirTexto(fila_inicial, columna_inicial, texto, estilo);
    }

    public void crearRegion(short fila_inicial, short columna_inicial, short fila_final, short columna_final) {
        Region region = new Region((short) (fila_inicial - 1), (short) (columna_inicial - 1), (short) (fila_final - 1), (short) (columna_final - 1));
        hoja.addMergedRegion(region);
        for (int x = fila_inicial - 1; x < fila_final; x++) {
            crearFila(x);
            for (int y = columna_inicial - 1; y < columna_final; y++)
                crearCelda(y);
        }
    }

    public void escribirFormula(int fila, int columna, String formula) {
        setFila(fila);
        setCelda(columna);
        celda.setCellType(TIPO_DATO_FORMULA);
        celda.setCellFormula(formula);
    }

    public void escribirNumero(double numero) {
        celda.setCellValue(numero);
    }

    public void escribirNumero(double numero, HSSFCellStyle estilo) {
        celda.setCellValue(numero);
        celda.setCellStyle(estilo);
    }

    public void escribirNumeroFormateado(double numero) {
        DataFormat format = libro.createDataFormat();
        HSSFCellStyle estilo = libro.createCellStyle();
        estilo.setDataFormat(format.getFormat("#,##0.0000"));
        celda.setCellStyle(estilo);
        celda.setCellValue(numero);
    }

    public void escribirNumeroFormateado(double numero, HSSFCellStyle estilo) {
        DataFormat format = libro.createDataFormat();
        estilo.setDataFormat(format.getFormat("#,##0.0000"));
        celda.setCellStyle(estilo);
        celda.setCellValue(numero);
    }

    public void escribirNumeroFormateado(int fila, int columna, double numero, HSSFCellStyle estilo) {
        setFila(fila);
        setCelda(columna);
        DataFormat format = libro.createDataFormat();
        estilo.setDataFormat(format.getFormat("#,##0.##"));
        celda.setCellStyle(estilo);
        celda.setCellValue(numero);
    }

    public void escribirNumero(int numero) {
        celda.setCellValue(numero);
    }

    public void escribirNumero(int numero, HSSFCellStyle estilo) {
        celda.setCellValue(numero);
        celda.setCellStyle(estilo);
    }

    public void escribirNumero(int fila, int columna, double numero) {
        setFila(fila);
        setCelda(columna);
        celda.setCellValue(numero);
    }

    public void escribirNumero(int fila, int columna, double numero, HSSFCellStyle estilo) {
        setFila(fila);
        setCelda(columna);
        celda.setCellValue(numero);
        celda.setCellStyle(estilo);
    }

    public void escribirNumero(int fila, int columna, int numero) {
        setFila(fila);
        setCelda(columna);
        celda.setCellValue(numero);
    }

    public void escribirNumero(int fila, int columna, int numero, HSSFCellStyle estilo) {
        setFila(fila);
        setCelda(columna);
        celda.setCellValue(numero);
        celda.setCellStyle(estilo);
    }

    public void escribirTexto(int fila, int columna, String texto) {
        setFila(fila);
        setCelda(columna);
        celda.setCellValue(texto);
    }

    public void escribirTexto(int fila, int columna, String texto, HSSFCellStyle estilo) {
        setFila(fila);
        setCelda(columna);
        celda.setCellValue(texto);
        celda.setCellStyle(estilo);
    }

    public void escribirTexto(String texto) {
        celda.setCellValue(texto);
    }

    public void escribirTexto(String texto, HSSFCellStyle estilo) {
        celda.setCellValue(texto);
        celda.setCellStyle(estilo);
    }

    public HSSFCellStyle getEstilo(short alineacion_vertical, short alineacion_horizontal) {
        HSSFCellStyle estilo = libro.createCellStyle();
        estilo.setAlignment(alineacion_horizontal);
        estilo.setVerticalAlignment(alineacion_vertical);

        return estilo;
    }

    public HSSFCellStyle getEstilo(short color_texto, short color_fondo, short estilo_texto, short alineacion_vertical, short alineacion_horizontal,
                                   short borde, String formato) {
        HSSFCellStyle estilo = libro.createCellStyle();
        HSSFFont font = libro.createFont();
        estilo.setAlignment(alineacion_horizontal);
        estilo.setVerticalAlignment(alineacion_vertical);
        estilo.setBorderBottom(borde);
        estilo.setBorderLeft(borde);
        estilo.setBorderTop(borde);
        estilo.setBorderRight(borde);
        estilo.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
        estilo.setFillBackgroundColor(color_fondo);

        font.setBoldweight(estilo_texto);
        font.setColor(color_texto);

        estilo.setFont(font);

        if (formato != null && formato.length() > 0) {
            HSSFDataFormat format = libro.createDataFormat();
            estilo.setDataFormat(format.getFormat(formato));
        }

        return estilo;
    }

    public HSSFCellStyle getColorFondo(short color_fondo) {
        HSSFCellStyle estilo = libro.createCellStyle();
        estilo.setFillPattern(HSSFCellStyle.FINE_DOTS);
        estilo.setFillBackgroundColor(color_fondo);
        return estilo;
    }

    public HSSFCellStyle getColor(short color_texto) {
        HSSFCellStyle estilo = libro.createCellStyle();
        HSSFFont font = libro.createFont();
        font.setColor(color_texto);

        estilo.setFont(font);
        return estilo;
    }

    /**
     * Si tipo negrilla, cursiva, etc . Ver tipos definidos en XLSDao
     * 
     * @param tipo_texto
     * @return
     */
    public HSSFCellStyle getTipoTexto(short tipo_texto) {
        HSSFCellStyle estilo = libro.createCellStyle();
        HSSFFont font = libro.createFont();
        font.setBoldweight(tipo_texto);
        estilo.setFont(font);

        return estilo;
    }

    public void setCeldaNegrilla(short fila, short columna) {
        setFila(fila);
        setCelda(columna);
        HSSFCellStyle estilo = celda.getCellStyle();
        HSSFFont font = libro.createFont();
        font.setBoldweight(XLSDao.ESTILO_TEXTO_NEGRILLA);
        estilo.setFont(font);
        celda.setCellStyle(estilo);
    }

    public String getNombreHoja(int numero_hoja) {
        return libro.getSheetName(numero_hoja);
    }

    public int getNumeroColumnas() {
        return fila.getPhysicalNumberOfCells();
    }

    public int getNumeroFila() {
        return fila.getRowNum() - 1;
    }

    public int getNumeroHoja(String nombre_hoja) {
        return libro.getSheetIndex(nombre_hoja);
    }

    /*
     * Metodos para guardar el Libro excel en un fichero
     */
    public void guardarLibro(String nombre_fichero) {
        FileOutputStream out;
        try {
            out = new FileOutputStream(nombre_fichero);
            libro.write(out);
            out.flush();
            out.close();
        } catch (FileNotFoundException e) {
        } catch (IOException e) {
        }
    }

    public void iniciar() {
        libro = new HSSFWorkbook();
        hoja = libro.createSheet("Hoja 1");
    }

    public void iniciar(HSSFWorkbook libro) {
        this.libro = libro;
    }

    /**
     * @param nombre_hoja
     *            Nombre de la hoja creada por defecto.
     */
    public void iniciar(String nombre_hoja) {
        libro = new HSSFWorkbook();
        hoja = libro.createSheet(nombre_hoja);
    }

    public void renombrarHoja(String nombre_hoja, String nombre_nuevo_hoja) {
        libro.setSheetName(getNumeroHoja(nombre_hoja), nombre_nuevo_hoja);
    }

    public void setAnchoColumna(short columna, int ancho) {
        hoja.setColumnWidth(columna - 1, (int) ((ancho * 8) / 0.05));
    }

    public void setCelda(int numero_columna) {
        if (fila.getCell(numero_columna - 1) == null) crearCelda(numero_columna);
        else celda = fila.getCell(numero_columna - 1);
        celda.setAsActiveCell();
    }

    public void setFila(int numero_fila) {
        if (hoja.getRow(numero_fila - 1) == null) crearFila((short) numero_fila);
        else fila = hoja.getRow(numero_fila - 1);
    }

    public void setHoja(int numero_hoja) {
        hoja = libro.getSheetAt(numero_hoja);
        hoja.setSelected(true);
    }

    public void setHoja(String nombre_hoja) {
        hoja = libro.getSheet(nombre_hoja);
        hoja.setSelected(true);
    }

    public void setOrdenHoja(String nombre_hoja, int orden) {
        String nombre_old = libro.getSheetName(orden - 1);
        libro.setSheetOrder(nombre_hoja, orden - 1);
        renombrarHoja(nombre_hoja, nombre_hoja + "2");
        renombrarHoja(nombre_old, nombre_hoja);
        renombrarHoja(nombre_hoja + "2", nombre_old);
    }

    public void setTipoCeldaNumero() {
        celda.setCellType(TIPO_DATO_NUMERICO);
    }

    public void setTipoCeldaTexto() {
        celda.setCellType(TIPO_DATO_TEXTO);
    }
}